package com.cn.auth.jwt;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author SHANGGUAN
 **/
@Builder
@AllArgsConstructor
public class JwtPayLoad implements JwtBaseEncrypt {

    /**
     * 签发人
     */
    @Getter
    private String iss;

    /**
     * 主题
     */
    @Getter
    private String sub;
    /**
     * 受众
     */
    @Getter
    private String aud;
    /**
     * 编号
     */
    @Getter
    private String jti;
    /**
     * 生效时间
     */
    @Getter
    private Long nbf;
    /**
     * 签发时间
     */
    @Getter
    private Long iat;
    /**
     * 过期时间
     */
    @Getter
    private Long exp;


    private static final Base64.Encoder encoder = Base64.getEncoder();
    private static final Base64.Decoder decoder = Base64.getDecoder();

    @Builder.Default
    private boolean isFirst = true;

    /**
     * 自定义属性
     */
    private final Map<Object, Object> claims = new HashMap<>();

    public void add(String key, Object value) {
        setBody();
        claims.putIfAbsent(key, value);
    }

    public Object getClaims(String key) {
        return claims.get(key);
    }

    /**
     * 生成PlyLoad
     *
     * @return {@link String }
     */
    public String plyLoad() {
        setBody();
        return JSON.toJSONString(claims);
    }

    /**
     * 通过Base64编码生成PlyLoad
     *
     * @return {@link String }
     */
    @Override
    public String encrypt() {
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(plyLoad().getBytes());
    }

    @Override
    public String decrypt(String encrypted) {
        byte[] decode = decoder.decode(encrypted);
        return new String(decode);
    }


    private void setBody() {
        if (isFirst) {
            String jsonString = JSON.toJSONString(this);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            Map<?, ?> javaMap = JSON.to(Map.class, jsonObject);
            claims.putAll(javaMap);
            isFirst = false;
        }
    }

    @SuppressWarnings("all")
    public static JwtPayLoad of(String payloadBase64) {
        byte[] decode = decoder.decode(payloadBase64);
        String jsonString = JSON.toJSONString(new String(decode));
        JSONObject jsonObject = JSON.parseObject(jsonString);
        Map<String, Object> javaMap = JSON.to(Map.class, jsonObject);
        return of(javaMap);
    }

    /**
     * 将Map转化为JwtPayLoad
     * <per>
     * 如果Map有多余属性会存在自定义的属性类
     * </per>
     *
     * @param map 地图
     * @return {@link JwtPayLoad }
     */
    public static JwtPayLoad of(Map<String, Object> map) {
        JwtPayLoadBuilder builder = JwtPayLoad.builder();
        Object iss = map.get("iss");
        Object sub = map.get("sub");
        Object aud = map.get("aud");
        Object jti = map.get("jti");
        Object nbf = map.get("nbf");
        Object iat = map.get("iat");
        Object exp = map.get("exp");
        if (iss != null) builder.iss(iss.toString());
        if (sub != null) builder.sub(sub.toString());
        if (aud != null) builder.aud(aud.toString());
        if (jti != null) builder.jti(jti.toString());
        if (nbf != null) builder.nbf(Long.parseLong(nbf.toString()));
        if (iat != null) builder.iat(Long.parseLong(iat.toString()));
        if (exp != null) builder.exp(Long.parseLong(exp.toString()));
        JwtPayLoad build = builder.build();
        map.forEach(build::add);
        return build;
    }


}
